package com.gitee.kamismile.stoneEureka.client.handler;

import com.gitee.kamismile.gatewayAgent.client.handler.GateWayClientHandler;
import com.gitee.kamismile.gatewayAgent.protobuf.Message;
import com.gitee.kamismile.stone.commmon.util.JsonUtil;
import com.gitee.kamismile.stone.commmon.util.ValueUtils;
import com.google.protobuf.ByteString;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import com.gitee.kamismile.stoneEureka.client.EurekaClientConstant;
import com.gitee.kamismile.stoneEureka.client.service.enreka.IEurekaClientService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.util.CollectionUtils;

import java.io.UnsupportedEncodingException;
import java.util.*;

public class EureKaClientHandler extends GateWayClientHandler {
    private final Logger logger = LoggerFactory.getLogger("bLog");

    private Channel channel;

    EurekaClientConstant eurekaClientConstant;

    EureKaClientGateWayClientHelper eureKaClientGateWayClientHelper;

    private ApplicationContext applicationContext;

    public EureKaClientGateWayClientHelper getEureKaClientGateWayClientHelper() {
        return eureKaClientGateWayClientHelper;
    }

    public void setEureKaClientGateWayClientHelper(EureKaClientGateWayClientHelper eureKaClientGateWayClientHelper) {
        this.eureKaClientGateWayClientHelper = eureKaClientGateWayClientHelper;
    }

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) {
        this.channel = ctx.channel();
        eureKaClientGateWayClientHelper.setChannel(this.channel);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Message.RouterMessage msg) throws Exception {
        logger.info(msg.toString());
        List<Message.RouterResponse> responseList = msg.getResponseList();
        if (CollectionUtils.isEmpty(responseList)) {
            return;
        }

        ctx.executor().execute(()->{
            responseList.stream().forEach(v -> {
                String data = null;
                try {
                    data = new String(v.getSerializedData().toByteArray(), "utf-8");
                } catch (UnsupportedEncodingException e) {

                }
                Map<String, Object> dataJson = ValueUtils.isNull(data) ? new HashMap<String, Object>() : JsonUtil.json2Map(data);
                dataJson.put("cmd", v.getCmd().getCommand());
                Collection<IEurekaClientService> eurekaClientServices = applicationContext.getBeansOfType(IEurekaClientService.class).values();
                eurekaClientServices.stream().filter(e -> e.isCmd(v.getCmd().getCommand())).forEach(e -> e.doService(dataJson,this));
            });
        });

    }

    public void sendMessage(String cmdInfo, String data, Long seq, String router) {
        Message.RouterMessage.Builder msg = Message.RouterMessage.newBuilder();
        Message.RouterRequest.Builder request = Message.RouterRequest.newBuilder();
        request.setSeq(seq);
        request.setRouter(router);
        Message.Command.Builder cmd = Message.Command.newBuilder();
        cmd.setCommand(cmdInfo);
        request.setCmd(cmd);
        request.setSerializedData(ByteString.copyFrom(data.getBytes()));
        msg.addRequest(request);
        channel.writeAndFlush(msg);
    }

    public EurekaClientConstant getEurekaClientConstant() {
        return eurekaClientConstant;
    }

    public void setEurekaClientConstant(EurekaClientConstant eurekaClientConstant) {
        this.eurekaClientConstant = eurekaClientConstant;
    }


    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }
}
